package datamining.algorithms.prefixspan;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import datamining.miner.enviroment.LocalEnvironment;
import datamining.miner.general.Embedding;
import datamining.miner.general.Frequency;
import datamining.miner.general.IndexedSequence;
import datamining.miner.general.SequenceFragment;
import datamining.sequence.HPSequence;
import datamining.sequence.IndexedItem;
import datamining.sequence.ItemSet;
import datamining.sequence.Sequence;

/**
 * <p>
 * 创建于 2012-12-7 下午9:21:49
 * 
 * @author xujinghu (jinghuxu@nudt.edu.cn) <br>
 *         Copyright 2012 xujinghu <br>
 *         Lisence: Apache
 */
public class PrefixSpanSequence<ItemType> implements IndexedSequence<ItemType> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Sequence<ItemType> original;
	private HPSequence<ItemType> hpSequence;
	public Frequency frequency;
	public int idx;
	public IndexedItem<ItemType> firstItem = null;
	public IndexedItem<ItemType> lastItem = null;

	public PrefixSpanSequence(Sequence<ItemType> original, int idx,
			Frequency frequency) {
		this.original = original;
		this.hpSequence = original.toHPSequence();
		this.firstItem = hpSequence.getFirstItem();
		this.lastItem = hpSequence.getLastItem();
		this.frequency = frequency;
		this.idx = idx;
	}

	@Override
	public Frequency frequency() {
		return frequency;
	}

	@Override
	public int getItemIndex(int itemSetIndex, Object lable) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getIndex() {
		// TODO Auto-generated method stub
		return idx;
	}

	@Override
	public Sequence<ItemType> toSequence() {
		return original;
	}

	/**
	 * 初始化搜索起始节点
	 * 
	 * @author xujinghu
	 * @date 2012-12-8下午11:44:43
	 * @param map
	 */
	public void createInitials(Map<ItemType, PrefixCode<ItemType>> map) {
		// TODO Auto-generated method stub
		final LocalEnvironment<ItemType> env = LocalEnvironment.env();
		final PThreadEnvironment<ItemType> tenv = (PThreadEnvironment<ItemType>) env
				.getThreadEnv(0);

		for (IndexedItem<ItemType> indexedItem = firstItem; indexedItem.next != null; indexedItem = indexedItem.next) {// 遍历所有项
			PrefixCode<ItemType> code = map.get(indexedItem.label);
			SequenceFragment<ItemType> frag;

			if (code == null) {
				// 构建新的序列
				Sequence<ItemType> subSequence = env
						.newSequence();
				subSequence.append(indexedItem.label, true);
				frag = tenv.getFragment(subSequence);
				code = tenv.getCode(frag, subSequence);
				map.put(indexedItem.label, code);
			} else {
				frag = code.toFragment();
			}

			if (env.storeEmbeddings) {
				frag.add(creatEmbedding(
						new IndexedItem<ItemType>(
								0,
								0,
								indexedItem.label),
						indexedItem, frag.toSequence()));
			} else {
				frag.add(this);
			}
		}
	}

	/**
	 * @author xujinghu
	 * @date 2012-12-20下午2:37:36
	 * @param subItem
	 *                子序列首项
	 * @param superItem
	 *                父序列首项
	 * @param subSequence
	 *                子序列
	 * @return 初始化的embedding
	 */
	Embedding<ItemType> creatEmbedding(IndexedItem<ItemType> subItem,
			IndexedItem<ItemType> superItem,
			Sequence<ItemType> subSequence) {
		Map<IndexedItem<ItemType>, IndexedItem<ItemType>> prefixMap = new TreeMap<IndexedItem<ItemType>, IndexedItem<ItemType>>();
		prefixMap.put(subItem, superItem);
		return new PrefixSpanEmbedding<ItemType>(subSequence, this,
				prefixMap);
	}

	public String toString() {
		return this.original.toString();
	}
}
